﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using DotNetNuke.Entities.Portals;
using DotNetNuke.Entities.Users;
using DotNetNuke.Modules.NBrightEspace.Components;
using NBrightCore.common;
using NBrightCore.render;
using NBrightDNN;
using System.Xml;

namespace DotNetNuke.Modules.NBrightEspace
{
    /// <summary>
    /// Summary description for XMLconnector
    /// </summary>
    public class XmlConnector : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            var strOut = "";

            if (UserController.GetCurrentUserInfo() != null)
            {
                    var paramCmd = Utils.RequestQueryStringParam(context, "cmd");
                    var itemId = Utils.RequestQueryStringParam(context, "itemid");
                    var ctlType = Utils.RequestQueryStringParam(context, "ctltype");
                    var idXref = Utils.RequestQueryStringParam(context, "idxref");
                    var xpathpdf = Utils.RequestQueryStringParam(context, "pdf");
                    var xpathref = Utils.RequestQueryStringParam(context, "pdfref");
                    var lang = Utils.RequestQueryStringParam(context, "language");
                    var selmonth = Utils.RequestQueryStringParam(context, "month");
                    var selyear = Utils.RequestQueryStringParam(context, "year");
                    var projectid = Utils.RequestQueryStringParam(context, "projectid");
                    var emp = Utils.RequestQueryStringParam(context, "emp");

                    var objCtrl = new Components.EspaceController();
                    NBrightInfo objPInfo;

                    switch (paramCmd)
                    {
                        case "test":
                            strOut = "<root>" + UserController.GetCurrentUserInfo().Username + "</root>";
                            break;
                        case "setdata":
                            if (Utils.IsNumeric(itemId))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {

                                    var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                    var inputxml = Utils.RequestParam(context, "inputxml");
                                    var strIn = HttpUtility.UrlDecode(inputxml);
                                    var xmlData = GenXmlFunctions.GetGenXmlByAjax(strIn, "");
                                    var objInfo = new NBrightInfo();
                                    objInfo.ItemID = -1;
                                    objInfo.TypeCode = ctlType + itemId;
                                    objInfo.XMLData = xmlData;
                                    objCtrl.Update(objInfo);
                                    strOut = GetReturnData(context, ctlType, itemId);
                                }
                            }
                            break;
                        case "deldata":
                            if (Utils.IsNumeric(itemId))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {

                                    var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                    if (obj.TypeCode.StartsWith(ctlType)) //make sure we are deleting correct type
                                    {
                                        objCtrl.Delete(Convert.ToInt32(itemId));
                                    }
                                    strOut = GetReturnData(context, ctlType, obj.TypeCode.Replace(ctlType, ""));
                                }
                                if (Utils.IsNumeric(idXref))
                                {
// Delete Reverse Xref if exists
                                    objCtrl.Delete(Convert.ToInt32(idXref));
                                }
                            }
                            break;
                        case "getdata":
                            strOut = GetReturnData(context, ctlType, itemId, GetSecuirtyClientId());
                            break;
                        case "getoutbal":
                            strOut = GetOutstandingBalance(context, itemId, GetSecuirtyClientId());
                            break;                            
                        case "getpdf":
                            if (Utils.IsNumeric(itemId))
                            {
                                var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                if (obj != null)
                                {
                                    var securityid = GetSecuirtyClientId();
                                    var cId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/clientid");
                                    if ((securityid == "Manager") | (cId == securityid) & (securityid != ""))
                                    {
                                        var invFilePath = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/" + xpathpdf);
                                        var invFileName = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/" + xpathref) + ".pdf";
                                        Utils.ForceDocDownload(HttpContext.Current.Server.MapPath(invFilePath), invFileName, context.Response);                                        
                                    }
                                }                                
                            }
                            break;
                        case "upddefurl":
                            if (Utils.IsNumeric(itemId))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {

                                    var websiteId = objCtrl.SetWebsiteDefaultUrl(Convert.ToInt32(itemId));
                                    strOut = GetReturnData(context, ctlType, websiteId);
                                }
                            }
                            break;
                        case "getclientxml":
                            if (Utils.IsNumeric(itemId))
                            {
                                var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                if (obj != null)
                                {
                                    var securityid = GetSecuirtyClientId();
                                    var cId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/clientid");
                                    if ((securityid == "Manager") | (cId == securityid) & (securityid != ""))
                                    {
                                        strOut = objCtrl.GetClientXML(Convert.ToInt32(itemId));
                                    }
                                }
                            }
                            break;
                        case "getclientrep":
                            if (Utils.IsNumeric(itemId))
                            {
                                var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                if (obj != null)
                                {
                                    var securityid = GetSecuirtyClientId();
                                    var cId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/clientid");
                                    if ((securityid == "Manager") | (cId == securityid) & (securityid != ""))
                                    {
                                        if (lang == "") lang = Utils.GetCurrentCulture();
                                        strOut = objCtrl.GetClientReport(Convert.ToInt32(itemId),lang);
                                    }
                                }
                            }
                            break;
                        case "delaction":
                            if (Utils.IsNumeric(itemId) && Utils.IsNumeric(idXref))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    var objInfo = objCtrl.GetByType(-1, -1, "ACTIONS" + itemId);
                                    objInfo.RemoveXmlNode("actions/action[id='" + idXref + "']");
                                    objCtrl.Update(objInfo);

                                    updateProgress(Convert.ToInt32(itemId), objInfo);

                                    strOut = GetReturnData(context, ctlType, itemId, GetSecuirtyClientId());
                                }
                            }
                            break;
                        case "updaction":
                            if (Utils.IsNumeric(itemId) && Utils.IsNumeric(idXref))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    var objInfo = objCtrl.GetByType(-1, -1, "ACTIONS" + itemId);
                                    var strValue = "False";
                                    if (Utils.RequestQueryStringParam(context, "flag").ToLower() == "false") strValue = "True";
                                    objInfo.SetXmlProperty("actions/action[id='" + idXref + "']/done",strValue);
                                    objCtrl.Update(objInfo);

                                    updateProgress(Convert.ToInt32(itemId),objInfo);

                                    strOut = GetReturnData(context, ctlType, itemId, GetSecuirtyClientId());
                                }
                            }
                            break;
                        case "getprogress":
                                objPInfo = objCtrl.Get(Convert.ToInt32(itemId));
                                strOut = objPInfo.GetXmlProperty("genxml/textbox/txtoverallprogress");
                                if (!Utils.IsNumeric(strOut)) strOut = "0";
                            break;
                        case "runsql":
                            if (Utils.IsNumeric(itemId))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    strOut = EspaceFunctions.GetReportHtml(itemId);
                                }
                            }
                            break;
                        case "gettimerep":
                            if (selmonth == "") selmonth = "-1";
                            if (selyear == "") selyear = "-1";
                            if (Utils.IsNumeric(projectid) && Utils.IsNumeric(selmonth) && Utils.IsNumeric(selyear))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    var obj = objCtrl.Get(Convert.ToInt32(projectid));
                                    if (obj != null)
                                    {
                                        if (lang == "") lang = Utils.GetCurrentCulture();
                                        strOut = objCtrl.GetTimeRep(Convert.ToInt32(projectid), lang, Convert.ToInt32(selmonth), Convert.ToInt32(selyear), emp);
                                    }
                                }
                            }
                            break;
                        case "gettimegrouprep":
                            if (selmonth == "") selmonth = "-1";
                            if (selyear == "") selyear = "-1";
                            if (Utils.IsNumeric(itemId) && Utils.IsNumeric(selmonth) && Utils.IsNumeric(selyear))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                    if (obj != null)
                                    {
                                        if (lang == "") lang = Utils.GetCurrentCulture();
                                        strOut = objCtrl.GetGroupTimeRep(Convert.ToInt32(itemId), lang, Convert.ToInt32(selmonth), Convert.ToInt32(selyear));
                                    }
                                }
                            }
                            break;
                        case "deltime":
                            if (selmonth == "") selmonth = "-1";
                            if (selyear == "") selyear = "-1";
                            if (Utils.IsNumeric(itemId) && Utils.IsNumeric(projectid) && Utils.IsNumeric(selmonth) && Utils.IsNumeric(selyear))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                    if (obj.TypeCode == "PROJTIME") //make sure we are deleting correct type
                                    {
                                        objCtrl.Delete(Convert.ToInt32(itemId));
                                        objCtrl.RecalcProjectTime(Convert.ToInt32(projectid));
                                    }
                                    if (lang == "") lang = Utils.GetCurrentCulture();
                                    strOut = objCtrl.GetTimeRep(Convert.ToInt32(projectid), lang, Convert.ToInt32(selmonth), Convert.ToInt32(selyear),emp);
                                }
                            }
                            break;
                        case "getcostrep":
                            if (selmonth == "") selmonth = "-1";
                            if (selyear == "") selyear = "-1";
                            if (Utils.IsNumeric(projectid) && Utils.IsNumeric(selmonth) && Utils.IsNumeric(selyear))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    var obj = objCtrl.Get(Convert.ToInt32(projectid));
                                    if (obj != null)
                                    {
                                        if (lang == "") lang = Utils.GetCurrentCulture();
                                        strOut = objCtrl.GetCostsRep(Convert.ToInt32(projectid), lang, Convert.ToInt32(selmonth), Convert.ToInt32(selyear));
                                    }
                                }
                            }
                            break;
                        case "delcost":
                            if (selmonth == "") selmonth = "-1";
                            if (selyear == "") selyear = "-1";
                            if (Utils.IsNumeric(itemId) && Utils.IsNumeric(projectid) && Utils.IsNumeric(selmonth) && Utils.IsNumeric(selyear))
                            {
                                if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
                                {
                                    var obj = objCtrl.Get(Convert.ToInt32(itemId));
                                    if (obj.TypeCode == "PROJCOST") //make sure we are deleting correct type
                                    {
                                        objCtrl.Delete(Convert.ToInt32(itemId));
                                        objCtrl.RecalcProjectCost(Convert.ToInt32(projectid));
                                    }
                                    if (lang == "") lang = Utils.GetCurrentCulture();
                                    strOut = objCtrl.GetCostsRep(Convert.ToInt32(projectid), lang, Convert.ToInt32(selmonth), Convert.ToInt32(selyear));
                                }
                            }
                            break;


                    }
            }



            //send back xml as plain text
            context.Response.Clear();
            context.Response.ContentType = "text/plain";
            if (strOut == "")
            {
                context.Response.Write("404 Not Found");
                context.Response.StatusCode = 404;
            }
            else
            {
                context.Response.Write(strOut);
            }
            context.Response.End();
        }


        private void updateProgress(int itemId, NBrightInfo objActionInfo)
        {
            var objCtrl = new Components.EspaceController();

            // update overall completed percentage
            Decimal actionsCount = 0, actionsTrue = 0, actionsFalse = 0;
            var xmlNodList = objActionInfo.XMLDoc.SelectNodes("actions/action");
            foreach (XmlNode xmlNod in xmlNodList)
            {
                actionsCount += 1;
                var selectSingleNode = xmlNod.SelectSingleNode("./done");
                if (selectSingleNode != null && selectSingleNode.InnerText.ToLower() == "true")
                {
                    actionsTrue += 1;
                }
                else
                {
                    actionsFalse += 1;
                }
            }

            Decimal overAll = ((100 / actionsCount) * actionsTrue);
            var objPInfo = objCtrl.Get(itemId);
            objPInfo.SetXmlProperty("genxml/textbox/txtoverallprogress", Math.Round(overAll).ToString(""));
            objCtrl.Update(objPInfo);
        }

        private string GetSecuirtyClientId()
        {
            var securityid = "";
            if (UserController.GetCurrentUserInfo().IsInRole("Manager"))
            {
                securityid = "Manager";
            }
            else
            {
                var objCtrl = new Components.EspaceController();
                var strFilter = " and ([xmlData].value('(genxml/textbox/txtusername)[1]', 'nvarchar(20)') = '" + UserController.GetCurrentUserInfo().Username + "')";
                var objL = objCtrl.GetList(-1,-1,"CLIENT", strFilter);
                if (objL.Count == 1)
                {
                    var obj = objL[0];
                    securityid = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/itemid");
                }
            }
            return securityid;
        }

        private string GetOutstandingBalance(HttpContext context, string itemId, string securityid = "Manager")
        {
            var sqlSearchFilter = " and ([xmlData].value('(genxml/hidden/clientid)[1]', 'nvarchar(10)') = '" + itemId + "')  and (convert(decimal(18,2),isnull(([xmlData].value('(genxml/hidden/dbltotaldue)[1]', 'money')),0)) > 0) ";
            var objCtrl = new Components.EspaceController();

            var objList = objCtrl.GetList(-1,-1,"INSTALLMENT%", sqlSearchFilter);
            decimal outTotal = 0 ;
 
            foreach (var obj in objList)
            {
                var cId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/clientid");
                if ((securityid == "Manager") | (cId == securityid))
                {
                    var tot = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/dbltotaldue");
                    if (Utils.IsNumeric(tot))
                    {
                        outTotal += Convert.ToDecimal(tot, CultureInfo.GetCultureInfo("en-US"));                        
                    }
                }
            }
            return outTotal.ToString("0.00");
        }


        private string GetReturnData(HttpContext context, string ctlType, string itemId, string securityid = "Manager")
        {
            var objCtrl = new EspaceController();
            var objSettings = objCtrl.GetByTypeCode("SETTINGS");

            var controlMapPath = objSettings.GetXmlProperty("genxml/hidden/controlmappath");
            if (controlMapPath == "")
            {
                return "ERROR: No ControlMapPath. To Set ControlMapPath go into settings and update";
            }
            var themeFolder = objSettings.GetXmlProperty("genxml/textbox/txtthemefolder");

            var moduleId = objSettings.GetXmlProperty("genxml/hidden/moduleid");
            if (!Utils.IsNumeric(moduleId))
            {
                return "ERROR: No ModuleId. To Set ModuleId go into settings and update";
            }

            var queryStrings = "";
            int loop1, loop2;
            // Load NameValueCollection object.
            NameValueCollection coll = context.Request.QueryString;
            // Get names of all keys into a string array.
            String[] arr1 = coll.AllKeys;
            for (loop1 = 0; loop1 < arr1.Length; loop1++)
            {
                if (arr1[loop1].Length > 1) // remove postback, unrequired params
                {
                    queryStrings += " " + arr1[loop1] + "=\"";
                    String[] arr2 = coll.GetValues(arr1[loop1]);
                    if (arr2 != null)
                    {
                        for (loop2 = 0; loop2 < arr2.Length; loop2++)
                        {
                            queryStrings += arr2[loop2] + "\" ";
                        }                        
                    }
                }
            }

            var strOut = "";
            var sqlSearchFilter = Utils.RequestQueryStringParam(context, "filter");
            var sqlOrderBy = Utils.RequestQueryStringParam(context, "orderby");

            var uInfo = new UserDataInfo(PortalSettings.Current.PortalId, Convert.ToInt32(moduleId), objCtrl, "NBrightAjax");

            var currentTabID =  uInfo.TabId;
            var currentModID = uInfo.ModuleId;
            var skinSrc = uInfo.SkinSrc;
            var objList = objCtrl.GetList(-1,-1,ctlType + itemId, sqlSearchFilter, sqlOrderBy);
            var xmlOut = "<root tabid=\"" + currentTabID + "\" mid=\"" + currentModID + "\" skinsrc=\"" + skinSrc + "\" " + queryStrings + ">";
            foreach (var obj in objList)
            {
                var cId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/clientid");
                if (cId=="")
                {//try for email foreignkey
                    cId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "genxml/hidden/clientidonemail");                    
                }
                if ((securityid == "Manager") | (cId == securityid))
                {
                    if (obj.XMLData.StartsWith("<root>"))
                    {
                        // Data is Xref, so read actual data required.
                        var xrefId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "root/xref");
                        if (Utils.IsNumeric(xrefId))
                        {
                            var obj2 = objCtrl.Get(Convert.ToInt32(xrefId));
                            if (obj2 != null)
                            {
                                var linedxrefId = GenXmlFunctions.GetGenXmlValue(obj.XMLData, "root/linkedxref");
                                xmlOut += "<item id=\"" + obj.ItemID.ToString("") + "\" idxref=\"" + linedxrefId + "\">" + obj2.XMLData + "</item>";
                            }
                        }
                    }
                    else
                    {
                        xmlOut += "<item id=\"" + obj.ItemID.ToString("") + "\">" + obj.XMLData + "</item>";
                    }
                }
            }
            xmlOut += "</root>";

            var templ = Utils.RequestQueryStringParam(context, "templ");
            var templCtrl = EspaceFunctions.GetTemplateGetter();
            var xslData = templCtrl.GetTemplateData(templ, Utils.GetCurrentCulture());
            
            //just check we have xslData, could be invalid setting
            if (xslData.ToUpper().StartsWith("NO")) return "ERROR (Try updating your settings): ControlMapPath=" + controlMapPath + "   xslfile=" + templ  +  " msg=" + xslData;

            try
            {
                strOut = NBrightCore.common.XslUtils.XslTransInMemory(xmlOut, xslData);
            }
            catch (Exception)
            {
                strOut = "ERROR: " + xslData;
            }
            return strOut;
        }


        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}